package com.xhga.transaction.common.jdbc;

import com.xhga.transaction.common.entity.TransactionLog;
import com.xhga.transaction.common.redis.RedisApi;
import com.xhga.transaction.common.redis.RedisConfig;
import com.xhga.transaction.common.service.TransactionLogService;
import com.xhga.transaction.common.util.UniqueUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by HuaWeiBo on 2019/5/5.
 */
public class TransactionLogJDBCService implements TransactionLogService{

    private static final Logger logger = LoggerFactory.getLogger(TransactionLogJDBCService.class);

    private UniqueUtil uniqueUtil;

    private RedisApi redisApi;

    public TransactionLogJDBCService(RedisApi redisApi) {
        this.uniqueUtil = new UniqueUtil(redisApi);
        this.redisApi = redisApi;
    }

    @Override
    public String getCentreNo(String type, String[] names, int count, String name) {
        return uniqueUtil.getRedisCentreNo(type, names, count, name);
    }

    @Override
    public void updateCentreNo(String type, String name, int count) {
        uniqueUtil.updateRedisCentreNo(type, name, count);
    }

    /**
     * 添加日志使用分布式锁
     * @param transactionLog
     * @return
     */
    @Override
    public int addTransactionLog(TransactionLog transactionLog) {
        String centreNo = transactionLog.getCentreNo();
        redisApi.lock(RedisConfig.LOCK_ADD_LOG + centreNo, centreNo);
        TransactionLog log = JdbcTransactionLog.getTransactionLogByCentreNo(centreNo);
        if (log != null) {
            logger.info("XHGA事务开启--已存在日志记录.no:{}", centreNo);
            redisApi.unLock(RedisConfig.LOCK_ADD_LOG + centreNo);
            return 0;
        }
        int result = JdbcTransactionLog.addTransactionLog(transactionLog);
        redisApi.unLock(RedisConfig.LOCK_ADD_LOG + centreNo);
        return result;
    }

    @Override
    public void updateFailedCount(String centreNo, String serverName) {
        logger.info("XHGA事务操作失败--serverName:{}.", serverName);
        // 修改分布式状态
        TransactionLog centre = JdbcTransactionLog.getTransactionLogByCentreNo(centreNo);
        if (centre == null) {
            return;
        }
        JdbcTransactionLog.updateFailedCount(centre.getId(), 0, 1);
    }

    @Override
    public void updatePrepareCount(String centreNo, String serverName) {
        int i = JdbcTransactionLog.updatePrepareCount(centreNo);
        String result = i > 0 ? "ok" : "fail";
        logger.info("XHGA事务--修改准备状态:{},结果:{}.", serverName, result);
    }

    @Override
    public int returnFailedCount(String centreNo) {
        // 无用
        return 0;
    }

    @Override
    public int returnFailedCountException(String centreNo) throws RuntimeException {
        // 无用
        return 0;
    }

    @Override
    public int returnFailedCountNoDelay(String centreNo) {
        // 无用
        return 0;
    }

    @Override
    public int returnFailedCountExceptionNoDelay(String centreNo) throws RuntimeException {
        TransactionLog transaction;
        while (true) {
            transaction = JdbcTransactionLog.getTransactionLogByCentreNo(centreNo);
            Integer prepareCount = transaction.getPrepareCount();
            Integer failedCount = transaction.getFailedCount();
            // 回滚
            if (failedCount > 0) {
                throw new RuntimeException();
            }
            if (prepareCount <= 0){
                if (failedCount != 0) {
                    throw new RuntimeException();
                }else {
                    return 0;
                }
            }
        }
    }

    public static void main(String[] args) {
        System.out.println(System.currentTimeMillis());
        int i = JdbcTransactionLog.updatePrepareCount("15566134731171883");
        System.out.println(System.currentTimeMillis());
        System.out.println(i);
    }
}
